package com.byit.interceptor;

import com.alibaba.fastjson.JSON;
import com.byit.domain.AppUser;
import com.byit.enums.PromptInfo;
import com.byit.jwt.domain.JwtSession;
import com.byit.jwt.lifecycle.JwtSessionLifecycleAspect;
import com.byit.jwt.utils.JWTUtil;
import com.byit.msg.MessageResult;
import com.byit.service.IAppUserService;
import com.byit.service.impl.AppUserServiceImpl;
import com.byit.utils.RedisUtil;
import com.byit.utils.SpringUtil;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 判断用户是否在其他设备上登录
 *
 * @author wangx
 */

public class AuthInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);

    /**
     * 需要排除的URL地址列表
     */
    private static final String[] excuseUrls = new String[]{
            "/app/login", "/app/home/bannerAndNotice", "/app/news/list",
            "/app/news/allNewsTypes", "/app/static/app/css", "/app/h5/aboutUs"
    };

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        IAppUserService userService = SpringUtil.getBean(AppUserServiceImpl.class);

        String uri = request.getRequestURI();
        if (uri.contains(".html") || uri.contains(".css")) {
            return true;
        }

        String authorization = request.getHeader("Authorization");

        /**
         * 判断token是否有效
         */
        if (authorization != null && !validateUrl(uri)) {
            JwtSession session = JWTUtil.getSession(authorization);
            if (session != null) {
                String token = (String) redisUtil.get(JwtSessionLifecycleAspect.KEY + session.userId());
                if (null != token && !authorization.equals(token)) { // 验证服务器的Session 与提交的Session一致。
                    PrintWriter writer = null;
                    try {
                        response.setCharacterEncoding("UTF-8");
                        response.setContentType("application/json; charset=utf-8");
                        writer = response.getWriter();
                        writer.write(JSON.toJSONString(MessageResult.warpper(PromptInfo.ACCOUNT_LOGIN_ERROR)));
                        writer.flush();
                        return false;
                    } catch (IOException e) {
                        logger.error("", e);
                    } finally {
                        IOUtils.closeQuietly(writer);
                    }
                }
                AppUser appUser = userService.selectById(session.userId());
                if (appUser.getStatus().compareTo(0) == 0) {
                    PrintWriter writer = null;
                    try {
                        response.setCharacterEncoding("UTF-8");
                        response.setContentType("application/json; charset=utf-8");
                        writer = response.getWriter();
                        writer.write(JSON.toJSONString(MessageResult.warpper(PromptInfo.ERROR_USER_LOSS)));
                        writer.flush();
                        return false;
                    } catch (IOException e) {
                        logger.error("", e);
                    } finally {
                        IOUtils.closeQuietly(writer);
                    }
                }
            }
        }
        return true;
    }

    /**
     * 验证需要排除的接口地址。
     *
     * @param uri 请求的URL地址
     * @return
     */
    private boolean validateUrl(String uri) {
        for (String excuseUrl : excuseUrls) {
            if (uri.indexOf(excuseUrl) != -1) {
                return true;
            }
        }
        return false;
    }
}